package com.emellend.api11.os;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Bundle;

public class RotationVectorDemo extends Activity {
	private SensorManager mSensorManager;
	private MyRenderer myRenderer;
	private GLSurfaceView mGlSurfaceView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
		myRenderer = new MyRenderer();
		mGlSurfaceView = new GLSurfaceView(this);
		mGlSurfaceView.setRenderer(myRenderer);
		setContentView(mGlSurfaceView);
	}
	class MyRenderer implements Renderer,SensorEventListener{
		private Cube mCube;
		private Sensor mRotationVectorSensor;
		private final float[] mRotationMatrix=new float[16];
		public MyRenderer() {
			mRotationVectorSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
			mCube=new Cube();
			mRotationMatrix[0]=1;
			mRotationMatrix[4]=1;
			mRotationMatrix[8]=1;
			mRotationMatrix[12]=1;
		}
		public void start() {
			mSensorManager.registerListener(this, mRotationVectorSensor,10000);
		}
		public void stop() {
			mSensorManager.unregisterListener(this);
		}
		@Override
		public void onAccuracyChanged(Sensor sensor, int accuracy) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onSensorChanged(SensorEvent event) {
			if (event.sensor.getType()==Sensor.TYPE_ROTATION_VECTOR) {
				SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values);
			}
		}

		@Override
		public void onDrawFrame(GL10 gl) {
			gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
			gl.glMatrixMode(GL10.GL_MODELVIEW);
			gl.glLoadIdentity();
			gl.glTranslatef(0, 0, -3.0f);
			gl.glMultMatrixf(mRotationMatrix, 0);
			  // draw our object
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

            mCube.draw(gl);
		}

		@Override
		public void onSurfaceChanged(GL10 gl, int width, int height) {
			// set view-port
            gl.glViewport(0, 0, width, height);
            // set projection matrix
            float ratio = (float) width / height;
            gl.glMatrixMode(GL10.GL_PROJECTION);
            gl.glLoadIdentity();
            gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
		}

		@Override
		public void onSurfaceCreated(GL10 gl, EGLConfig config) {
			 // dither is enabled by default, we don't need it
            gl.glDisable(GL10.GL_DITHER);
            // clear screen in white
            gl.glClearColor(1,1,1,1);
		}
		class Cube{
			private FloatBuffer mVertexBuffer;
			private FloatBuffer mColorBuffer;
			private ByteBuffer mIndexBuffer;
			
			public Cube() {
				final float vertices[] = {
                        -1, -1, -1,		 1, -1, -1,
                         1,  1, -1,	    -1,  1, -1,
                        -1, -1,  1,      1, -1,  1,
                         1,  1,  1,     -1,  1,  1,
                };

                final float colors[] = {
                        0,  0,  0,  1,  1,  0,  0,  1,
                        1,  1,  0,  1,  0,  1,  0,  1,
                        0,  0,  1,  1,  1,  0,  1,  1,
                        1,  1,  1,  1,  0,  1,  1,  1,
                };

                final byte indices[] = {
                        0, 4, 5,    0, 5, 1,
                        1, 5, 6,    1, 6, 2,
                        2, 6, 7,    2, 7, 3,
                        3, 7, 4,    3, 4, 0,
                        4, 7, 6,    4, 6, 5,
                        3, 0, 1,    3, 1, 2
                };
                
                ByteBuffer vbb=ByteBuffer.allocateDirect(vertices.length*4);
                vbb.order(ByteOrder.nativeOrder());
                mVertexBuffer=vbb.asFloatBuffer();
                mVertexBuffer.put(vertices);
                mVertexBuffer.position(0);
                
                ByteBuffer cbb=ByteBuffer.allocateDirect(colors.length*4);
                cbb.order(ByteOrder.nativeOrder());
                mColorBuffer=cbb.asFloatBuffer();
                mColorBuffer.put(colors);
                mColorBuffer.position(0);
                
                mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
                mIndexBuffer.put(indices);
                mIndexBuffer.position(0);
			}
			public void draw(GL10 gl){
				gl.glEnable(GL10.GL_CULL_FACE);
				gl.glFrontFace(GL10.GL_CW);
				gl.glShadeModel(GL10.GL_SMOOTH);
				gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
				gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer);
				gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, mIndexBuffer);
			}
		}
		
	}
}
